﻿using System;
using System.Collections.Generic;
using System.Configuration.Provider;
using System.IO;
using System.Web;
using TallComponents.Web.Pdf;

namespace TallComponents.Web.Storage
{
   /// <summary>
   /// Manages PDF documents using a storage manager.
   /// </summary>
   public abstract class PdfStorageProvider : ProviderBase, IPdfStorage
   {
      /// <summary>
      /// Gets information about a PDF document.
      /// </summary>
      /// <param name="key">The storage key.</param>
      /// <returns>A <see cref="Document"/> object describing the document with the specified <paramref name="key"/> or <c>null</c> if the key is not valid or associated with an invalid document.</returns>
      public abstract Document GetDocument( string key );

      /// <summary>
      /// Gets information on all the documents in storage.
      /// </summary>
      /// <returns>A list of <see cref="Document"/> objects, describing all PDF documents managed by this provider.</returns>
      public abstract IList<Document> GetDocuments();

      /// <summary>
      /// Gets the page.
      /// </summary>
      /// <remarks>
      /// This method is used when rendering a page to an image.
      /// <para>When overriding this method, return <c>null</c> if a page is not available for any reason.
      /// Do not throw exceptions.</para></remarks>
      /// <param name="key">The unique key for the document.</param>
      /// <param name="pageIndex">Index of the page.</param>
      /// <returns>The requested page or <c>null</c>.</returns>
      public virtual Page GetPage( string key, int pageIndex )
      {
         var document = GetDocument( key );

         if ( null != document )
         {
            if ( pageIndex < 0 )
               pageIndex = 0;
            if ( pageIndex >= document.Pages.Count )
               pageIndex = document.Pages.Count - 1;

            return document.Pages[ pageIndex ];
         }

         return null;
      }

      /// <summary>
      /// Stores an uploaded file.
      /// </summary>
      /// <param name="file">The uploaded file.</param>
      /// <returns>The unique key for the file.</returns>
      public string StoreFile( HttpPostedFile file )
      {
         if ( null == file )
            throw new ArgumentNullException( "file" );

         using ( var stream = file.InputStream )
         {
            return StoreFile( file.FileName, stream );
         }
      }

      /// <summary>
      /// Stores a file.
      /// </summary>
      /// <param name="fileName">Name of the file.</param>
      /// <param name="data">A seekable stream containing the file data.</param>
      /// <returns>The unique key for the file.</returns>
      public abstract string StoreFile( string fileName, Stream data );
   }
}
